#include "Game Commander.h"

//Initializers and Deinitializers

//This is the only other function called in WinMain
FunctionReturn GAME::Initialize(HWND hWnd,HINSTANCE hInst,HINSTANCE hPrevInst,int nCmdShow,LPSTR lpCmdLine)
{
	assert(hWnd != NULL);
	m_hWnd = hWnd;
	assert(hInst != NULL);
	assert(hPrevInst == NULL);
	assert(lpCmdLine != NULL);

	//Seed randomizer
	srand(unsigned(time(0)));

	//Singleton inits go here
	Graphics::Engine()->Initialize(hWnd);
	SoundEngine::Engine()->LoadSounds("M&GSounds");
	Input::Engine()->Init(hWnd, hInst);
#ifdef SMALL 
	Board::Engine()->Init(SMALL_MAP_SIZE);
#endif
#ifdef MEDIUM 
	Board::Engine()->Init(MEDIUM_MAP_SIZE);
#endif
#ifdef LARGE 
	Board::Engine()->Init(LARGE_MAP_SIZE);
#endif


	m_eGameState = GAME_INIT_STATE;

	return SUCCEED;
}

FunctionReturn GAME::CleanUp()
{
	//All decontruction and deletion goes here
	//delete m_pMenu; //This is broken and can't be deleted for some strange reason

	m_MenuList->Clear();

	delete m_MenuList;
	return SUCCEED;
}

//Game Tools
double GAME::CLOCK()
{
	//Initializes now and then
	static double now;
	static double then = timeGetTime();
	//Updates now
	now = timeGetTime();
	//Used to check with
	static double TimeTotal = 0;
	//How long has it been
	// add to total
	double TimeTemp = ( now - then ) * .001f;
	TimeTotal += TimeTemp;
	then = now;
	//If it has been a second, update and reset
	if(TimeTotal >= WAIT_TIME)
	{
		TICK(SET_TIME);
		TimeTotal = 0;
	}
	//Time Since last call
	m_dElapsedTime = TimeTemp;
	//Total in game time
	m_dTotalGameTime += TimeTemp;

	return TimeTemp;
}

bool GAME::TICK(int Type)
{
	if(Type == SET_TIME)
	{
		m_bSetTimeElapsed = true;
		return false;
	}
	if(Type == CHECK_TIME)
	{
		bool temp = m_bSetTimeElapsed;
		m_bSetTimeElapsed = false;
		return temp;
	}
	return false;
}

bool GAME::LOSE(int L)
{
	static bool ifLOST = false;
	if(L == YES)
	{
		ifLOST = true;
		return false;
	}
	if(L == IF)
	{
		bool temp = ifLOST;
		ifLOST = false;
		return temp;
	}
	return false;
}

bool GAME::WIN(int W)
{
	static bool ifWON = false;
	if(W == YES)
	{
		ifWON = true;
		return false;
	}
	if(W == IF)
	{
		bool temp = ifWON;
		ifWON = false;
		return temp;
	}
	return false;
}

FunctionReturn GAME::INITGAME()
{

	//Any Other inits go here
	Player1 = new Player(PLAYER_ONE);
	RETURN_CHECK( Player1->SetCurrentSpace(Board::Engine()->GetFirstSpace()) );
	Player2 = new Player(PLAYER_TWO);
	RETURN_CHECK( Player2->SetCurrentSpace(Board::Engine()->GetFirstSpace()) );
	Player1->AddMaterial(MAT_IRON, 10);
	m_pGameDeck = new Deck;

	m_pMenu = new Menu();
	m_MenuList = new DrawList;
	m_MenuList->Init();
	m_pMenu->Init();
	m_MenuList->add(m_pMenu);
	for  (int i = 0; i < 2; i++)
	{
		m_MenuList->add((BaseObject*)(m_pMenu->m_MainMenuButtons[i]));
	}
	//Set the text to draw in the same rect as the buttons
	Graphics::Engine()->m_textarray[0].m_rect = m_pMenu->m_MainMenuButtons[0]->m_buttonRECT;
	Graphics::Engine()->m_textarray[1].m_rect = m_pMenu->m_MainMenuButtons[1]->m_buttonRECT;
	Graphics::Engine()->m_textarray[2].m_rect = m_pMenu->m_InGameButtons[2]->m_buttonRECT;
	Graphics::Engine()->m_textarray[3].m_rect = m_pMenu->m_InGameButtons[3]->m_buttonRECT;
	Graphics::Engine()->m_textarray[4].m_rect = m_pMenu->m_InGameButtons[4]->m_buttonRECT;
	Graphics::Engine()->m_textarray[5].m_rect = m_pMenu->m_InGameButtons[5]->m_buttonRECT;

	m_ObjectDrawList = new DrawList;
	m_ObjectDrawList->Init();
	m_ObjectDrawList->add(Player1);
	m_ObjectDrawList->add(Player2);
	m_pGameDeck->createDeck("Deck.txt");

	return SUCCEED;
}

//Game state functions
FunctionReturn GAME::DRAW()
{
	//Draws the specified list of objects
	//return succeed if data was found and used correctly
	switch(m_eGameState)
	{
	case GAME_MENU_STATE:
		Graphics::Engine()->Draw(m_MenuList);
		return SUCCEED;

	case GAME_UPDATE_STATE:

		//Graphics::Engine()->Draw(m_ObjectDrawList);

		m_MenuList->add(m_pMenu);

		//UPDATE LATER TO INCLUDE ALL INGAME BUTTONS
		for (int i = 0; i < 6; i++)
		{
			m_MenuList->add((BaseObject*)(m_pMenu->m_InGameButtons[i]));
		}
		//////////////
		//Combine all three lists from the board, menu and objects (menu, buttons, etc)
		//////////////
		m_MenuList->AddVector(*Board::Engine()->GetDrawList());
		m_MenuList->AddVector(*m_ObjectDrawList);
		Graphics::Engine()->Draw(m_MenuList);

		m_MenuList->Clear();

		return SUCCEED;
	}
	return SUCCEED;
}

FunctionReturn GAME::INPUT(POINT& mousepoint)
{
	//Check input
	//return succeed if data was found and used correctly
	Input::Engine()->PollDevices();

	switch(m_eGameState)
	{
	case GAME_MENU_STATE:
		//In the menu only draw the start and quit button.
		Graphics::Engine()->m_textarray[START].ifDraw = true;
		Graphics::Engine()->m_textarray[QUIT].ifDraw = true;
		Graphics::Engine()->m_textarray[IRON].ifDraw = false;
		Graphics::Engine()->m_textarray[SULFUR].ifDraw = false;
		Graphics::Engine()->m_textarray[GEM].ifDraw = false;
		Graphics::Engine()->m_textarray[FORFIET].ifDraw = false;
		Graphics::Engine()->m_textarray[UPDATE_TEXT].ifDraw = false;
		if(m_pMenu->m_MainMenuButtons[0]->CheckIfPressed(mousepoint))
		{
			m_eGameState = GAME_UPDATE_STATE;
			m_pMenu->SwitchMenus();
			m_iCurrPlayer = 1;
		}

		if(m_pMenu->m_MainMenuButtons[1]->CheckIfPressed(mousepoint))
		{
			//Exit game 
			m_eGameState = GAME_QUIT_STATE;
		}
		return SUCCEED;

	case GAME_UPDATE_STATE:
		Graphics::Engine()->m_textarray[START].ifDraw = false;
		Graphics::Engine()->m_textarray[QUIT].ifDraw = false;
		Graphics::Engine()->m_textarray[IRON].ifDraw = true;
		Graphics::Engine()->m_textarray[SULFUR].ifDraw = true;
		Graphics::Engine()->m_textarray[GEM].ifDraw = true;
		Graphics::Engine()->m_textarray[FORFIET].ifDraw = true;
		Graphics::Engine()->m_textarray[UPDATE_TEXT].ifDraw = true;
		m_pMenu->m_InGameButtons[0]->textureIndex = CARD;

		if(m_iCurrPlayer == 1)
		{
			Graphics::Engine()->m_textarray[UPDATE_TEXT].m_String = "Game Info:\nPlayer 1's Turn!";

			if(m_pMenu->m_InGameButtons[0]->CheckIfPressed(mousepoint))
			{
				Card* tempcard;
				ostringstream tempString;
				ostringstream tempStringSul;
				ostringstream tempStringGem;
				//Add any card input updates here
				tempcard = m_pGameDeck->drawCard();
				m_pMenu->m_InGameButtons[0]->textureIndex = tempcard->returnType();
				Player1->Move((eTileType)(tempcard->returnType()));
				m_iCurrPlayer = 2;

				//Text Update
				tempString << "Iron:\n" << Player2->GetIron();
				Graphics::Engine()->m_textarray[IRON].m_String = tempString.str();
				
				tempStringSul << "Sulfur:\n" << Player2->GetSulfur();
				Graphics::Engine()->m_textarray[SULFUR].m_String = tempStringSul.str();
				
				tempStringGem << "Gem:\n" << Player2->GetGem();
				Graphics::Engine()->m_textarray[GEM].m_String = tempStringGem.str();
				

				return SUCCEED;
			}
			if(m_pMenu->m_InGameButtons[1]->CheckIfPressed(mousepoint))
			{
				//Creation input updates
			}
			if(m_pMenu->m_InGameButtons[2]->CheckIfPressed(mousepoint))
			{
				//Item1 updates
				if(Player1->UseItem(PICKAXE_ITEM) == SUCCEED)
				SoundEngine::Engine()->PlayCue("mine");
			}
			if(m_pMenu->m_InGameButtons[3]->CheckIfPressed(mousepoint))
			{
				//Item2 updates
				if(Player1->UseItem(TNT_ITEM) == SUCCEED)
					SoundEngine::Engine()->PlayCue("bomb");
			}
			if(m_pMenu->m_InGameButtons[4]->CheckIfPressed(mousepoint))
			{
				//Item3 updates	
			}
			
		}
		if(m_iCurrPlayer == 2)
		{
			Graphics::Engine()->m_textarray[UPDATE_TEXT].m_String = "Game Info:\nPlayer 2's Turn!";

			if(m_pMenu->m_InGameButtons[0]->CheckIfPressed(mousepoint))
			{
				Card* tempcard;
				ostringstream tempString;
				ostringstream tempStringSul;
				ostringstream tempStringGem;
				//Add any card input updates here
				tempcard = m_pGameDeck->drawCard();
				m_pMenu->m_InGameButtons[0]->textureIndex = tempcard->returnType();
				Player2->Move((eTileType)(tempcard->returnType()));
				m_iCurrPlayer = 1;

				tempString << "Iron:\n" << Player1->GetIron();
				Graphics::Engine()->m_textarray[IRON].m_String = tempString.str();
				tempStringSul << "Sulfur:\n" << Player1->GetSulfur();
				Graphics::Engine()->m_textarray[SULFUR].m_String = tempStringSul.str();
				tempStringGem << "Gem:\n" << Player1->GetGem();
				Graphics::Engine()->m_textarray[GEM].m_String = tempStringGem.str();

				return SUCCEED;
			}
			if(m_pMenu->m_InGameButtons[1]->CheckIfPressed(mousepoint))
			{
				//Creation input updates
			}
			if(m_pMenu->m_InGameButtons[2]->CheckIfPressed(mousepoint))
			{
				//Item1 Updates
				Player2->UseItem(PICKAXE_ITEM);
				SoundEngine::Engine()->PlayCue("mine");
			}
			if(m_pMenu->m_InGameButtons[3]->CheckIfPressed(mousepoint))
			{
				//Item2 updates
				Player2->UseItem(TNT_ITEM);
				SoundEngine::Engine()->PlayCue("bomb");
			}
			if(m_pMenu->m_InGameButtons[4]->CheckIfPressed(mousepoint))
			{
				//Item3 updates	
			}
		}
		if(m_pMenu->m_InGameButtons[5]->CheckIfPressed(mousepoint))
		{
			//Forfeit Updates	
			GAME::INITGAME();
			m_eGameState = GAME_MENU_STATE;
		}
		if(Input::Engine()->keyPressed(DIK_ESCAPE))
		{
			m_eGameState = GAME_QUIT_STATE;
		}
		return SUCCEED;
	}
	return SUCCEED;
}

FunctionReturn GAME::UPDATE()
{
	//Updates all objects
	Player1->Update((float)m_dElapsedTime);
	Player2->Update((float)m_dElapsedTime);
	return SUCCEED;
}

FunctionReturn GAME::WORK(POINT& mousepoint)
{
	static bool Ended = false;

	switch(m_eGameState)
	{
	case GAME_INIT_STATE:
		INITGAME();
		DRAW();
		m_eGameState = GAME_MENU_STATE;
		return SUCCEED;
	case GAME_INTRO_STATE:
		INPUT(mousepoint);
		DRAW();
		return SUCCEED;
	case GAME_MENU_STATE:
		SoundEngine::Engine()->PlayCue("underworld");
		INPUT(mousepoint);
		DRAW();
		return SUCCEED;
	case GAME_UPDATE_STATE:
		CLOCK();
		UPDATE();
		DRAW();

		//Waits to check input until a second has passed
		if(TICK(CHECK_TIME) && !Player1->IfMoving() && !Player2->IfMoving())
			INPUT(mousepoint);
		return SUCCEED;
	case GAME_QUIT_STATE:		
		CleanUp();
		PostQuitMessage(0);
		return SUCCEED;

	case GAME_NULL_STATE:

		//In case of initialization failure
		return UNKNOWN;
	}
	return MISSING_DATA;
}

